//md5 1041d5b2aa5ea58692472f832aac4d3e
(function() {
  var _, _expr, _importLib, all0, all1, bin, cat, cfg, chdl_base, dec, expand, fft, fft_tb, has0, has1, hasEven1, hasOdd1, hex, infer, mem, mem_mux, oct;

  chdl_base = require('chdl_base');

  ({_expr} = require('chdl_utils'));

  ({cat, expand, all1, all0, has0, has1, hasOdd1, hasEven1} = require('chdl_operator'));

  ({infer, hex, oct, bin, dec} = require('chdl_base'));

  ({_importLib} = require('chdl_transpiler_engine'));

  module.paths.push('/home/lisiyu/work/project/fft/src');

  _ = require("lodash");

  cfg = {
    bank_num: 4,
    cell_num: 1,
    data_width: 64,
    addr_width: 32,
    data_mem_depth: 256,
    exp_mem_depth: 512,
    instr_mem_depth: 12288,
    instr_width: 16
  };

  fft = _importLib('./fft.chdl', __dirname);

  mem_mux = _importLib('./mem_mux.chdl', __dirname);

  mem = _importLib('./mem_model.chdl', __dirname);

  fft_tb = class fft_tb extends chdl_base.Module {
    constructor() {
      var bank_list, bank_unit, i, idx, j, k, l, len, len1, len2, mem_unit, ref, ref1, unit;
      super();
      this.v_helper = this._mixinas(_importLib('verilog_helpers.chdl', __dirname));
      this.cell_num = cfg.cell_num;
      this.data_width = cfg.data_width;
      this.addr_width = cfg.addr_width;
      this.bank_num = cfg.bank_num;
      this.data_mem_depth = cfg.data_mem_depth;
      this.exp_mem_depth = cfg.exp_mem_depth;
      this.instr_mem_depth = cfg.instr_mem_depth;
      this.instr_width = cfg.instr_width;
      this._cellmap({
        fft_u0: new fft(this.cell_num, this.addr_width, this.data_width)
      });
      bank_list = [];
      ref = _.range(this.bank_num);
      for (j = 0, len = ref.length; j < len; j++) {
        i = ref[j];
        unit = new mem(this.data_width, this.data_mem_depth, 1);
        bank_list.push(unit);
      }
      bank_unit = {};
      for (idx = k = 0, len1 = bank_list.length; k < len1; idx = ++k) {
        mem_unit = bank_list[idx];
        bank_unit["data_mem_bank_" + idx] = mem_unit;
      }
      this._cellmap(bank_unit);
      this._cellmap({
        instr_mem_u0: new mem(this.instr_width, this.instr_mem_depth, 1)
      });
      this._cellmap({
        exp_mem_u0: new mem(this.data_width, this.exp_mem_depth, 1)
      });
      this._cellmap({
        mux_u0: new mem_mux(this.cell_num, this.bank_num, this.data_width, this.data_mem_depth, "round")
      });
      this._cellmap({
        mux_u1: new mem_mux(1, 2, this.instr_width, this.instr_mem_depth, "round")
      });
      this._cellmap({
        mux_u2: new mem_mux(1, 2, this.data_width, this.exp_mem_depth, "round")
      });
      this._port();
      this._wire();
      this._reg({
        clk: this._localVreg(),
        rstn: this._localVreg()
      });
      this._channel({
        fft_ch: this.mold(this.fft_u0),
        data_mem_port_ch: this.createArray(this.bank_num, () => {
          return chdl_base.channel();
        }),
        instr_mem_port_ch: this.mold(this.instr_mem_u0),
        exp_mem_port_ch: this.mold(this.exp_mem_u0),
        mux_ch: this.mold(this.mux_u0),
        instr_mux_ch: this.mold(this.mux_u1),
        exp_mux_ch: this.mold(this.mux_u2)
      });
      ref1 = _.range(this.bank_num);
      for (l = 0, len2 = ref1.length; l < len2; l++) {
        i = ref1[l];
        bank_list[i].bind({
          mem_port: this.data_mem_port_ch[i]
        });
      }
      this.setDefaultClock('clk');
      this.setDefaultReset('rstn');
    }

    build() {
      var i, j, k, len, len1, ref, ref1;
      this.v_helper.create_clock(this.clk, 10);
      this.v_helper.create_resetn(this.rstn);
      ref = _.range(this.bank_num);
      
      //fft_port = $stubPort(@fft_ch)
      for (j = 0, len = ref.length; j < len; j++) {
        i = ref[j];
        this._channelPortHub(this.mux_ch.mem[i], this.data_mem_port_ch[i]);
      }
      this._channelPortHub(this.instr_mux_ch.mem[0], this.instr_mem_port_ch);
      this._channelPortHub(this.exp_mux_ch.mem[0], this.exp_mem_port_ch);
      ref1 = _.range(this.cell_num);
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        i = ref1[k];
        this._channelPortHub(this.fft_ch.sram[i], this.mux_ch.mem_req[i]);
      }
      this._channelPortHub(this.fft_ch.instr_sram, this.instr_mux_ch.mem_req[0]);
      return this._channelPortHub(this.fft_ch.exp_sram, this.exp_mux_ch.mem_req[0]);
    }

  };

  module.exports = fft_tb;

  return module.exports;

}).call(this);
